﻿/* MVT Charts for Silverlight - Version 1
 * 2008 by Mario Meir-Huber
 * mailto: i-mameir@microsoft.com
 *         mario@meirhuber.de
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ChartLibrary.Data;
using System.Globalization;
using System.Diagnostics;
using ChartLibrary.Base;

/*
 * ChartLibrary.Charts is the Namespace for all charts.
 */ 
namespace ChartLibrary.Charts
{
    /// <summary>
    /// this displays an AreaChart
    /// </summary>
    public partial class AreaChart : AxisCharts
    {
        public event ItemHandler ItemMouseEnter;  //occurs when the mouse enters the item
        public event ItemHandler ItemMouseLeave;  //occurs when the mouse leaves the item
        public event ItemHandler ItemClicked;     //occurs when a mouse click is performed on the item

        /// <summary>
        /// Creates a new AreaChart
        /// </summary>
        public AreaChart()
        {
            this.SizeChanged += new SizeChangedEventHandler(PointChart_SizeChanged);
            this.Loaded += new RoutedEventHandler(PointChart_Loaded);
            this.DrawAreaChanged += new StateChangedEvent(AreaChart_DrawAreaChanged);
        }

        /// <summary>
        /// updates if the Drawable area was changed
        /// </summary>
        void AreaChart_DrawAreaChanged()
        {
            UpdateChart();
        }

        /// <summary>
        /// Updates the Chart when the Control is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void PointChart_Loaded(object sender, RoutedEventArgs e)
        {
            UpdateChart();
        }

        /// <summary>
        /// Updates the Chart when the Control is resized
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void PointChart_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateChart();
        }

        /// <summary>
        /// updates the Chart
        /// </summary>
        private void UpdateChart()
        {
            double max = Data.Max;
            double min = Data.Min;
            Shape tmpelem;
            Line tmpline = null;

            Polygon pgTemp = null;

            Point lastPoint = new Point();

            double singleleft;
            int j = -1;
            bool firstpoint = true;

            Storyboard sttemp = null;
            Storyboard stlineanim = null;

            double singletop = (Area.Height - Area.StartY) / (max - min);

            //draws area and points/lines for every datasource
            foreach (DataSource ds in Data)
            {
                j++;
                singleleft = (Area.Width - Area.StartX) / (ds.Length - 1);

                firstpoint = true;

                //draws each data point
                for (int i = 0; i < ds.Length; i++)
                {
                    //check if it is the first point
                    if (firstpoint)
                    {
                        lastPoint.X = singleleft * i + Area.StartX;
                        lastPoint.Y = Area.Height - (ds[i].Value - min) * singletop + Area.StartY;

                        tmpline = null;
                        firstpoint = false;
                    }
                    else
                    {
                        tmpline = LayoutRoot.FindName("_lnmarker_" + i.ToString() + "_" + j.ToString()) as Line;

                        if (null == tmpline)
                        {
                            tmpline = new Line();
                            tmpline.SetValue(Canvas.NameProperty, "_lnmarker_" + i.ToString() + "_" + j.ToString());

                            tmpline.RenderTransform = new TranslateTransform();
                            tmpline.Stroke = ds.Fill;
                            tmpline.StrokeThickness = 1;

                            LayoutRoot.Children.Add(tmpline);
                        }

                        //displays the line
                        tmpline.X1 = lastPoint.X;
                        tmpline.Y1 = lastPoint.Y;

                        tmpline.X2 = singleleft * i + Area.StartX;
                        tmpline.Y2 = Area.Height - (ds[i].Value - min) * singletop;

                        lastPoint.X = tmpline.X2;
                        lastPoint.Y = tmpline.Y2;

                        pgTemp = LayoutRoot.FindName("_areamarker_" + i.ToString() + "_" + j.ToString()) as Polygon;

                        if (null != pgTemp) LayoutRoot.Children.Remove(pgTemp);

                        //displays the area
                        pgTemp = new Polygon();

                        pgTemp.SetValue(Canvas.NameProperty, "_areamarker_" + i.ToString() + "_" + j.ToString());
                        pgTemp.Fill = ds.Fill;
                        pgTemp.OpacityMask = new SolidColorBrush(Color.FromArgb(50, 0, 0, 0));

                        LayoutRoot.Children.Add(pgTemp);

                        pgTemp.Points.Add(new Point(tmpline.X1, Area.Height + Area.StartY));
                        pgTemp.Points.Add(new Point(tmpline.X1, tmpline.Y1));
                        pgTemp.Points.Add(new Point(tmpline.X2, tmpline.Y2));
                        pgTemp.Points.Add(new Point(tmpline.X2, Area.Height + Area.StartY));
                        pgTemp.Points.Add(new Point(tmpline.X1, Area.Height + Area.StartY));
                    }

                    //displays the points
                    tmpelem = LayoutRoot.FindName("_ptmarker_" + i.ToString() + "_" + j.ToString()) as Shape;

                    if (null == tmpelem)
                    {
                        tmpelem = GenerateItem();
                        tmpelem.SetValue(Canvas.NameProperty, "_ptmarker_" + i.ToString() + "_" + j.ToString());
                        tmpelem.Fill = ds.Fill;

                        tmpelem.RenderTransform = new TranslateTransform();

                        LayoutRoot.Children.Add(tmpelem);

                        tmpelem.MouseEnter += new MouseEventHandler(OnItemEnter);
                        tmpelem.MouseLeave += new MouseEventHandler(OnItemLeave); 
                        tmpelem.MouseLeftButtonUp += new MouseButtonEventHandler(OnItemClick);
                    }

                    tmpelem.SetValue(Canvas.LeftProperty, lastPoint.X - 4.0);
                    tmpelem.SetValue(Canvas.TopProperty, lastPoint.Y - 4.0);

                    //adds an storyboard
                    sttemp = MakeStoryBoard(tmpelem, sttemp, i, lastPoint.X - 4.0, lastPoint.Y - 4.0);

                    if (null != tmpline)
                    {
                        stlineanim = MakeStoryBoard(tmpelem, sttemp, i, singleleft * i, Area.Height - (ds[i].Value - min) * singletop, tmpline);
                        //LayoutRoot.Resources.Add(stlineanim);
                        stlineanim.Completed += new EventHandler(stlineanim_Completed);
                        //stlineanim.Begin();
                    }

                    //LayoutRoot.Resources.Add(sttemp);

                    sttemp.Completed += new EventHandler(sttemp_Completed);
                    //sttemp.Begin();

                }
            }
        }

        /// <summary>
        /// Occurs when the mouse enters an item
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnItemLeave(object sender, MouseEventArgs e)
        {
            if (null != ItemMouseLeave) ItemMouseLeave(sender, new ItemEventArgs());
        }

        /// <summary>
        /// Occurs when an item was clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnItemClick(object sender, MouseButtonEventArgs e)
        {
            if (null != ItemClicked)
            {
                ItemClicked(sender, new ItemEventArgs());
            }
        }

        /// <summary>
        /// Occurs when the mouse enters an item
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnItemEnter(object sender, MouseEventArgs e)
        {
            if (null != ItemMouseEnter) ItemMouseEnter(sender, new ItemEventArgs());
        }

        /// <summary>
        /// removes the storyboard if animation is completed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void stlineanim_Completed(object sender, EventArgs e)
        {
            Storyboard st = (Storyboard)sender;
            //LayoutRoot.Resources.Remove(st);
        }

        /// <summary>
        /// this generates a new storyboard for a single point
        /// </summary>
        /// <param name="tmpelem">Element that should be animated</param>
        /// <param name="sttemp">Storyboard to use</param>
        /// <param name="AsynchID">Indicates if it should be used Asynchronous</param>
        /// <param name="xpos">Animate to an X Position</param>
        /// <param name="ypos">Animate to an Y Position</param>
        /// <returns></returns>
        private Storyboard MakeStoryBoard(UIElement tmpelem, Storyboard sttemp, int AsynchID, double xpos, double ypos)
        {
            string initstory = "";

            double calculated_length = 2.0;

            if (Data.Count > 0)
            {
                calculated_length /= Data[0].Length;
            }

            switch (Animation)
            {
                case ChartLibrary.Base.Animation.FxOpacity:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.Opacity)\" " +
                        "BeginTime=\"00:00:00\"><SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5000000\" Value=\"1\"/></DoubleAnimationUsingKeyFrames></Storyboard>";
                        break;
                    }
                case ChartLibrary.Base.Animation.FxOpacityAsynchrounous:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.Opacity)\" " +
                        "BeginTime=\"00:00:00\"><SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.2 * AsynchID * calculated_length, 3)).ToString(new NumberFormatInfo() 
                                                { CurrencyDecimalSeparator = "." }) + "\" Value=\"1\"/></DoubleAnimationUsingKeyFrames></Storyboard>";
                        break;
                    }
                case ChartLibrary.Base.Animation.FxCenterPoint:
                    {
                        double new_xpos = Math.Round(ActualWidth / 2 - xpos, 2);
                        double new_ypos = Math.Round(ActualHeight / 2 - ypos, 2);

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_xpos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +

                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxCenterPointAsynchronous:
                    {
                        double new_xpos = Math.Round(ActualWidth / 2 - xpos, 2);
                        double new_ypos = Math.Round(ActualHeight / 2 - ypos, 2);

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_xpos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() 
                                                                    { CurrencyDecimalSeparator = "." }) + "\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() 
                                                                    { CurrencyDecimalSeparator = "." }) + "\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +

                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxDropDownAsynchronous:
                    {
                        double new_ypos = ypos * -1;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.1, 3)).ToString(new NumberFormatInfo()
                                                                    { CurrencyDecimalSeparator = "." }) + "\" Value=\"10\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo()
                                                                    { CurrencyDecimalSeparator = "." }) + "\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +

                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxDropDown:
                    {
                        double new_ypos = ypos * -1;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (0.4).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"10\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (0.5).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +

                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxRiseUpAsynchronous:
                    {
                        double new_ypos = ActualHeight - ypos;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.1, 3)).ToString(new NumberFormatInfo()
                                                                    { CurrencyDecimalSeparator = "." }) + "\" Value=\"-10\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() 
                                                                    { CurrencyDecimalSeparator = "." }) + "\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +

                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxRiseUp:
                    {
                        double new_ypos = ActualHeight - ypos;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tmpelem.GetValue(Canvas.NameProperty).ToString() + "\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + new_ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (0.4).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"-10\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (0.5).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"0\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +

                        "</Storyboard>";

                        break;
                    }
                default:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\" />";
                        break;
                    }
            }

            sttemp = (Storyboard)System.Windows.Markup.XamlReader.Load(initstory);
            return sttemp;
        }

        /// <summary>
        /// Generates a Storyboard
        /// </summary>
        /// <param name="tmpelem">Element to be used</param>
        /// <param name="sttemp">Storyboard</param>
        /// <param name="AsynchID">indicates the asynch ID to use</param>
        /// <param name="xpos">Y Position to animate to</param>
        /// <param name="ypos">X Position to animate to</param>
        /// <param name="tmpline">Line that should be used</param>
        /// <returns></returns>
        private Storyboard MakeStoryBoard(UIElement tmpelem, Storyboard sttemp, int AsynchID, double xpos, double ypos, UIElement tmpline)
        {
            string initstory = "";
            string tline = (string)tmpline.GetValue(Canvas.NameProperty);

            double x1pos = (double)tmpline.GetValue(Line.X1Property);
            double y1pos = (double)tmpline.GetValue(Line.Y1Property);

            double calculated_length = 2.0;

            if (Data.Count > 0)
            {
                calculated_length /= Data[0].Length;
            }

            switch (Animation)
            {
                case ChartLibrary.Base.Animation.FxOpacity:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Opacity)\" " +
                        "BeginTime=\"00:00:00\"><SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5000000\" Value=\"1\"/></DoubleAnimationUsingKeyFrames></Storyboard>";
                        break;
                    }
                case ChartLibrary.Base.Animation.FxOpacityAsynchrounous:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Opacity)\" " +
                        "BeginTime=\"00:00:00\"><SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.2 * AsynchID * calculated_length, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"1\"/></DoubleAnimationUsingKeyFrames></Storyboard>";
                        break;
                    }
                case ChartLibrary.Base.Animation.FxCenterPoint:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (ActualHeight / 2).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (ActualHeight / 2).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + y1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.X2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (ActualWidth / 2).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + xpos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.X1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (ActualHeight / 2).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + x1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxCenterPointAsynchronous:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (Math.Round(ActualHeight / 2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:0" + (Math.Round(0.1 * (AsynchID - 1)  * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (Math.Round(ActualHeight / 2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:0" + (Math.Round(0.1 * AsynchID  * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + y1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.X2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (Math.Round(ActualWidth / 2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:0" + (Math.Round(0.1 * (AsynchID - 1)  * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + xpos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.X1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + (Math.Round(ActualHeight / 2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:0" + (Math.Round(0.1 * AsynchID  * calculated_length + 0.2, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + x1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxDropDownAsynchronous:
                    {
                        double new_ypos = ActualHeight - ypos;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.1, 2)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + (ypos + 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * AsynchID * calculated_length + 0.2, 2)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * (AsynchID - 1) * calculated_length  + 0.1, 2)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + (y1pos + 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round(0.1 * (AsynchID - 1) * calculated_length +  0.2, 2)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + y1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxDropDown:
                    {
                        double new_ypos = ActualHeight - ypos;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.4\" Value=\"" + (ypos + 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"0\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.4\" Value=\"" + (y1pos + 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + y1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxRiseUpAsynchronous:
                    {
                        double new_ypos = ActualHeight - ypos;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + ActualHeight.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round((0.1 * AsynchID  + 0.1) * calculated_length, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + (ypos - 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round((0.1 * AsynchID  + 0.2 )* calculated_length, 3)).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + ActualHeight.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round((0.1 * (AsynchID  - 1 )  + 0.1 )* calculated_length, 3) ).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + (y1pos - 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:" + (Math.Round((0.1 * (AsynchID  - 1) + 0.2) * calculated_length , 3) ).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\" Value=\"" + y1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "</Storyboard>";

                        break;
                    }
                case ChartLibrary.Base.Animation.FxRiseUp:
                    {
                        double new_ypos = ActualHeight - ypos;

                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\">" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y2)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + ActualHeight.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.4\" Value=\"" + (ypos - 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + ypos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "<DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"" + tline + "\" Storyboard.TargetProperty=\"(UIElement.Y1)\" " +
                        "BeginTime=\"00:00:00\">" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00\" Value=\"" + ActualHeight.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.4\" Value=\"" + (y1pos - 10).ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "<SplineDoubleKeyFrame KeyTime=\"00:00:00.5\" Value=\"" + y1pos.ToString(new NumberFormatInfo() { CurrencyDecimalSeparator = "." }) + "\"/>" +
                        "</DoubleAnimationUsingKeyFrames>" +
                        "</Storyboard>";

                        break;
                    }
                default:
                    {
                        initstory = "<Storyboard xmlns=\"http://schemas.microsoft.com/client/2007\" />";
                        break;
                    }
            }

            try
            {
                sttemp = (Storyboard)System.Windows.Markup.XamlReader.Load(initstory);
            }
            catch
            {
                sttemp = new Storyboard();
            }

            return sttemp;
        }

        /// <summary>
        /// this removes the storyboard if it is completed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void sttemp_Completed(object sender, EventArgs e)
        {
            Storyboard st = (Storyboard)sender;
            //LayoutRoot.Resources.Remove(st);
        }

        /// <summary>
        /// this generates a new shape for the markers
        /// </summary>
        /// <returns></returns>
        private Shape GenerateItem()
        {

            if (ItemType == ChartLibrary.Base.ItemType.PointCircle)
            {
                Shape retval = new Ellipse();

                retval.Width = 8;
                retval.Height = 8;

                return retval;
            }

            if (ItemType == ChartLibrary.Base.ItemType.PointRectangle)
            {
                Shape retval = new Rectangle();
                retval.Width = 8;
                retval.Height = 8;


                return retval;
            }

            if (ItemType == ChartLibrary.Base.ItemType.PointTriangle)
            {
                Polygon retval = new Polygon();
                retval.Points.Add(new Point(0, 8));
                retval.Points.Add(new Point(5, 0));
                retval.Points.Add(new Point(10, 8));

                return retval;
            }

            return null;
        }
    }
}
